package com.trace.demo.controller;

import com.trace.demo.entity.ProcessingInfo;
import com.trace.demo.entity.ProcessingStep;
import com.trace.demo.entity.Product;
import com.trace.demo.repository.ProcessingInfoRepository;
import com.trace.demo.repository.ProcessingStepRepository;
import com.trace.demo.repository.ProductRepository;
import com.trace.demo.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 加工信息控制器
 */
@RestController
@RequestMapping("/api/processing")
public class ProcessingInfoController {

    @Autowired
    private ProcessingInfoRepository processingInfoRepository;

    @Autowired
    private ProcessingStepRepository processingStepRepository;

    @Autowired
    private ProductRepository productRepository;

    /**
     * 获取所有加工信息（分页）
     */
    @GetMapping
    public ResponseEntity<ApiResponse<Map<String, Object>>> getAllProcessingInfo(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) Long productId,
            @RequestParam(required = false) String factory,
            @RequestParam(required = false) String[] dateRange) {

        try {
            // 创建分页请求
            Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by("id").descending());

            Page<ProcessingInfo> page;

            // 根据条件进行查询
            if (productId != null && factory != null && !factory.isEmpty()) {
                page = processingInfoRepository.findByProductIdAndProcessingFactoryContaining(productId, factory, pageable);
            } else if (dateRange != null && dateRange.length == 2) {
                LocalDate startDate = LocalDate.parse(dateRange[0]);
                LocalDate endDate = LocalDate.parse(dateRange[1]);
                page = processingInfoRepository.findByProcessingDateBetween(startDate, endDate, pageable);
            } else {
                page = processingInfoRepository.findAll(pageable);
            }

            // 转换为Map格式
            List<Map<String, Object>> content = page.getContent().stream()
                    .map(this::convertToMap)
                    .collect(Collectors.toList());

            // 创建分页响应
            Map<String, Object> response = new HashMap<>();
            response.put("content", content);
            response.put("totalElements", page.getTotalElements());
            response.put("totalPages", page.getTotalPages());
            response.put("size", page.getSize());
            response.put("number", page.getNumber());

            return ResponseEntity.ok(new ApiResponse<>(true, "获取加工信息列表成功", response));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取加工信息列表失败: " + e.getMessage(), null));
        }
    }

    /**
     * 获取单个加工信息
     */
    @GetMapping("/{id}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getProcessingInfoById(@PathVariable Long id) {
        try {
            Optional<ProcessingInfo> processingInfoOpt = processingInfoRepository.findById(id);
            if (!processingInfoOpt.isPresent()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "加工信息不存在: " + id, null));
            }

            // 获取加工步骤
            List<ProcessingStep> steps = processingStepRepository.findByProcessingInfoIdOrderByStepOrder(id);

            // 转换为Map
            Map<String, Object> result = convertToMap(processingInfoOpt.get());

            // 添加加工步骤
            result.put("steps", steps);

            return ResponseEntity.ok(new ApiResponse<>(true, "获取加工信息成功", result));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取加工信息失败: " + e.getMessage(), null));
        }
    }

    /**
     * 创建加工信息
     */
    @PostMapping
    @Transactional
    public ResponseEntity<ApiResponse<Map<String, Object>>> createProcessingInfo(
            @RequestBody Map<String, Object> requestBody) {
        try {
            // 获取产品ID
            Long productId = null;
            if (requestBody.get("productId") != null) {
                if (requestBody.get("productId") instanceof Integer) {
                    productId = Long.valueOf((Integer) requestBody.get("productId"));
                } else if (requestBody.get("productId") instanceof Long) {
                    productId = (Long) requestBody.get("productId");
                } else {
                    productId = Long.parseLong(requestBody.get("productId").toString());
                }
            }

            if (productId == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body(new ApiResponse<>(false, "产品ID不能为空", null));
            }

            // 检查产品是否存在
            Optional<Product> productOpt = productRepository.findById(productId);
            if (!productOpt.isPresent()) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                        .body(new ApiResponse<>(false, "产品不存在: " + productId, null));
            }

            // 创建加工信息
            ProcessingInfo processingInfo = new ProcessingInfo();
            processingInfo.setProduct(productOpt.get());

            // 设置基本字段
            if (requestBody.get("processingFactory") != null) {
                processingInfo.setProcessingFactory(requestBody.get("processingFactory").toString());
            }

            if (requestBody.get("processingAddress") != null) {
                processingInfo.setProcessingAddress(requestBody.get("processingAddress").toString());
            }

            if (requestBody.get("processingDate") != null) {
                processingInfo.setProcessingDate(LocalDate.parse(requestBody.get("processingDate").toString()));
            }

            if (requestBody.get("packagingDate") != null) {
                processingInfo.setPackagingDate(LocalDate.parse(requestBody.get("packagingDate").toString()));
            }

            if (requestBody.get("shelfLife") != null) {
                processingInfo.setShelfLife(requestBody.get("shelfLife").toString());
            }

            if (requestBody.get("storageMethods") != null) {
                processingInfo.setStorageMethods(requestBody.get("storageMethods").toString());
            }

            if (requestBody.get("processingTechnology") != null) {
                processingInfo.setProcessingTechnology(requestBody.get("processingTechnology").toString());
            }

            if (requestBody.get("inspectionReportUrl") != null) {
                processingInfo.setInspectionReportUrl(requestBody.get("inspectionReportUrl").toString());
            }

            // 设置创建和更新时间
            processingInfo.setCreatedAt(LocalDateTime.now());
            processingInfo.setUpdatedAt(LocalDateTime.now());

            // 保存加工信息
            ProcessingInfo savedProcessingInfo = processingInfoRepository.save(processingInfo);

            // 处理加工步骤
            List<Map<String, Object>> stepsData = (List<Map<String, Object>>) requestBody.get("steps");
            List<ProcessingStep> savedSteps = new ArrayList<>();

            if (stepsData != null && !stepsData.isEmpty()) {
                int stepOrder = 1;
                for (Map<String, Object> stepData : stepsData) {
                    ProcessingStep step = new ProcessingStep();
                    step.setProcessingInfo(savedProcessingInfo);
                    step.setStepOrder(stepOrder++);

                    if (stepData.get("name") != null) {
                        step.setName(stepData.get("name").toString());
                    }

                    if (stepData.get("description") != null) {
                        step.setDescription(stepData.get("description").toString());
                    }

                    savedSteps.add(processingStepRepository.save(step));
                }
            }

            // 转换为Map
            Map<String, Object> result = convertToMap(savedProcessingInfo);

            // 添加加工步骤
            result.put("steps", savedSteps);

            return ResponseEntity.status(HttpStatus.CREATED)
                    .body(new ApiResponse<>(true, "创建加工信息成功", result));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "创建加工信息失败: " + e.getMessage(), null));
        }
    }

    /**
     * 更新加工信息
     */
    @PutMapping("/{id}")
    @Transactional
    public ResponseEntity<ApiResponse<Map<String, Object>>> updateProcessingInfo(
            @PathVariable Long id,
            @RequestBody Map<String, Object> requestBody) {
        try {
            // 检查加工信息是否存在
            Optional<ProcessingInfo> processingInfoOpt = processingInfoRepository.findById(id);
            if (!processingInfoOpt.isPresent()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "加工信息不存在: " + id, null));
            }

            ProcessingInfo processingInfo = processingInfoOpt.get();

            // 更新产品信息
            if (requestBody.get("productId") != null) {
                Long productId;
                if (requestBody.get("productId") instanceof Integer) {
                    productId = Long.valueOf((Integer) requestBody.get("productId"));
                } else if (requestBody.get("productId") instanceof Long) {
                    productId = (Long) requestBody.get("productId");
                } else {
                    productId = Long.parseLong(requestBody.get("productId").toString());
                }

                // 检查产品是否存在
                Optional<Product> productOpt = productRepository.findById(productId);
                if (!productOpt.isPresent()) {
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                            .body(new ApiResponse<>(false, "产品不存在: " + productId, null));
                }

                processingInfo.setProduct(productOpt.get());
            }

            // 更新基本字段
            if (requestBody.get("processingFactory") != null) {
                processingInfo.setProcessingFactory(requestBody.get("processingFactory").toString());
            }

            if (requestBody.get("processingAddress") != null) {
                processingInfo.setProcessingAddress(requestBody.get("processingAddress").toString());
            }

            if (requestBody.get("processingDate") != null) {
                processingInfo.setProcessingDate(LocalDate.parse(requestBody.get("processingDate").toString()));
            }

            if (requestBody.get("packagingDate") != null) {
                processingInfo.setPackagingDate(LocalDate.parse(requestBody.get("packagingDate").toString()));
            }

            if (requestBody.get("shelfLife") != null) {
                processingInfo.setShelfLife(requestBody.get("shelfLife").toString());
            }

            if (requestBody.get("storageMethods") != null) {
                processingInfo.setStorageMethods(requestBody.get("storageMethods").toString());
            }

            if (requestBody.get("processingTechnology") != null) {
                processingInfo.setProcessingTechnology(requestBody.get("processingTechnology").toString());
            }

            if (requestBody.get("inspectionReportUrl") != null) {
                processingInfo.setInspectionReportUrl(requestBody.get("inspectionReportUrl").toString());
            }

            // 更新更新时间
            processingInfo.setUpdatedAt(LocalDateTime.now());

            // 保存加工信息
            ProcessingInfo updatedProcessingInfo = processingInfoRepository.save(processingInfo);

            // 处理加工步骤
            List<Map<String, Object>> stepsData = (List<Map<String, Object>>) requestBody.get("steps");

            if (stepsData != null) {
                // 删除所有现有步骤
                processingStepRepository.deleteByProcessingInfoId(id);

                // 添加新步骤
                List<ProcessingStep> updatedSteps = new ArrayList<>();
                int stepOrder = 1;

                for (Map<String, Object> stepData : stepsData) {
                    ProcessingStep step = new ProcessingStep();
                    step.setProcessingInfo(updatedProcessingInfo);
                    step.setStepOrder(stepOrder++);

                    if (stepData.get("name") != null) {
                        step.setName(stepData.get("name").toString());
                    }

                    if (stepData.get("description") != null) {
                        step.setDescription(stepData.get("description").toString());
                    }

                    updatedSteps.add(processingStepRepository.save(step));
                }

                // 获取更新后的加工步骤
                List<ProcessingStep> steps = processingStepRepository.findByProcessingInfoIdOrderByStepOrder(id);

                // 转换为Map
                Map<String, Object> result = convertToMap(updatedProcessingInfo);

                // 添加加工步骤
                result.put("steps", steps);

                return ResponseEntity.ok(new ApiResponse<>(true, "更新加工信息成功", result));
            } else {
                // 获取现有加工步骤
                List<ProcessingStep> steps = processingStepRepository.findByProcessingInfoIdOrderByStepOrder(id);

                // 转换为Map
                Map<String, Object> result = convertToMap(updatedProcessingInfo);

                // 添加加工步骤
                result.put("steps", steps);

                return ResponseEntity.ok(new ApiResponse<>(true, "更新加工信息成功", result));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "更新加工信息失败: " + e.getMessage(), null));
        }
    }

    /**
     * 删除加工信息
     */
    @DeleteMapping("/{id}")
    @Transactional
    public ResponseEntity<ApiResponse<Void>> deleteProcessingInfo(@PathVariable Long id) {
        try {
            // 检查加工信息是否存在
            if (!processingInfoRepository.existsById(id)) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "加工信息不存在: " + id, null));
            }

            // 删除所有关联的加工步骤
            processingStepRepository.deleteByProcessingInfoId(id);

            // 删除加工信息
            processingInfoRepository.deleteById(id);

            return ResponseEntity.ok(new ApiResponse<>(true, "删除加工信息成功", null));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "删除加工信息失败: " + e.getMessage(), null));
        }
    }

    /**
     * 根据产品ID获取加工信息
     */
    @GetMapping("/product/{productId}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getProcessingInfoByProductId(@PathVariable Long productId) {
        try {
            Optional<ProcessingInfo> processingInfoOpt = processingInfoRepository.findByProductId(productId);
            if (!processingInfoOpt.isPresent()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new ApiResponse<>(false, "该产品的加工信息不存在: " + productId, null));
            }

            ProcessingInfo processingInfo = processingInfoOpt.get();

            // 获取加工步骤
            List<ProcessingStep> steps = processingStepRepository.findByProcessingInfoIdOrderByStepOrder(processingInfo.getId());

            // 转换为Map
            Map<String, Object> result = convertToMap(processingInfo);

            // 添加加工步骤
            result.put("steps", steps);

            return ResponseEntity.ok(new ApiResponse<>(true, "获取产品加工信息成功", result));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ApiResponse<>(false, "获取产品加工信息失败: " + e.getMessage(), null));
        }
    }

    /**
     * 将ProcessingInfo转换为Map
     */
    private Map<String, Object> convertToMap(ProcessingInfo processingInfo) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", processingInfo.getId());
        map.put("productId", processingInfo.getProduct() != null ? processingInfo.getProduct().getId() : null);
        map.put("productName", processingInfo.getProduct() != null ? processingInfo.getProduct().getProductName() : null);
        map.put("processingFactory", processingInfo.getProcessingFactory());
        map.put("processingAddress", processingInfo.getProcessingAddress());
        map.put("processingDate", processingInfo.getProcessingDate());
        map.put("packagingDate", processingInfo.getPackagingDate());
        map.put("shelfLife", processingInfo.getShelfLife());
        map.put("storageMethods", processingInfo.getStorageMethods());
        map.put("processingTechnology", processingInfo.getProcessingTechnology());
        map.put("inspectionReportUrl", processingInfo.getInspectionReportUrl());
        map.put("createdAt", processingInfo.getCreatedAt());
        map.put("updatedAt", processingInfo.getUpdatedAt());
        return map;
    }
}
